package com.nineclock.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.system.dto.DepartmentOrUserSimpleDTO;
import com.nineclock.system.dto.SysDepartmentDTO;
import com.nineclock.system.mapper.SysCompanyUserMapper;
import com.nineclock.system.mapper.SysDepartmentMapper;
import com.nineclock.system.pojo.SysCompanyUser;
import com.nineclock.system.pojo.SysDepartment;
import com.nineclock.system.service.SysDepartmentService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.text.CollationElementIterator;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class SysDepartmentServiceImpl implements SysDepartmentService {
    @Autowired
    private SysDepartmentMapper departmentMapper;
    @Autowired
    private SysCompanyUserMapper companyUserMapper;
    @Override
    public List<SysDepartmentDTO> getDepartment() {
        LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        wrapper.eq(SysDepartment::getParentId,0);
        List<SysDepartment> departmentList = departmentMapper.selectList(wrapper);
        List<SysDepartmentDTO> departmentDTOList = BeanHelper.copyWithCollection(departmentList, SysDepartmentDTO.class);
        getDepartmentChild(departmentDTOList);
        return departmentDTOList;
    }

    @Override
    public List<Long> getAllDepartmentId() {

        LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
        List<SysDepartment> departmentList = departmentMapper.selectList(wrapper);
        if (!CollectionUtils.isEmpty(departmentList)){

            List<Long> idList = departmentList.stream().map(SysDepartment::getId).collect(Collectors.toList());
            return idList;
        }
        return null;
    }

    @Override
    public List<DepartmentOrUserSimpleDTO> querySimpleDepartment(Long id, Integer includeMember) {
        if (id == null || includeMember == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        List<DepartmentOrUserSimpleDTO> dtoList = new ArrayList<>();
        if (includeMember == 0) {
            LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysCompanyUser::getDepartmentId, id);
            wrapper.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
            wrapper.eq(SysCompanyUser::getEnable, 1);
            List<SysCompanyUser> companyUserList = companyUserMapper.selectList(wrapper);
            if (!CollectionUtils.isEmpty(companyUserList)) {
                for (SysCompanyUser sysCompanyUser : companyUserList) {
                    DepartmentOrUserSimpleDTO departmentOrUserSimpleDTO = new DepartmentOrUserSimpleDTO();
                    departmentOrUserSimpleDTO.setId(sysCompanyUser.getId());
                    departmentOrUserSimpleDTO.setName(sysCompanyUser.getUserName());
                    departmentOrUserSimpleDTO.setType(2);
                    dtoList.add(departmentOrUserSimpleDTO);
                }
            }
        }
        LambdaQueryWrapper<SysDepartment> wrapperDepartment = new LambdaQueryWrapper<>();
        wrapperDepartment.eq(SysDepartment::getCompanyId,CurrentUserHolder.get().getCompanyId());
        wrapperDepartment.eq(SysDepartment::getParentId,id);
        List<SysDepartment> departmentList = departmentMapper.selectList(wrapperDepartment);
        if (!CollectionUtils.isEmpty(departmentList)){
            for (SysDepartment sysDepartment : departmentList) {
                DepartmentOrUserSimpleDTO departmentOrUserSimpleDTO = new DepartmentOrUserSimpleDTO();
                departmentOrUserSimpleDTO.setId(sysDepartment.getId());
                departmentOrUserSimpleDTO.setName(sysDepartment.getName());
                departmentOrUserSimpleDTO.setType(1);
                dtoList.add(departmentOrUserSimpleDTO);
            }
        }
        return dtoList;
    }

    @Override
    public List<Long> getAllDepIdByCompanyUserId(Long companyUserId) {
        List<Long> idList = new ArrayList<>();
        SysCompanyUser sysCompanyUser = companyUserMapper.selectById(companyUserId);
        if (sysCompanyUser != null){
            getAllParentDeptIdWithSortById(sysCompanyUser.getDepartmentId(),idList);
        }
        return idList;
    }

    private void getAllParentDeptIdWithSortById(Long departmentId, List<Long> idList) {
        idList.add(departmentId);
        SysDepartment sysDepartment = departmentMapper.selectById(departmentId);
        if (sysDepartment != null && sysDepartment.getParentId() != 0){
            idList.add(sysDepartment.getParentId());
            getAllParentDeptIdWithSortById(sysDepartment.getParentId(), idList);
        }
    }


    private void getDepartmentChild(List<SysDepartmentDTO> departmentDTOList) {

        for (SysDepartmentDTO sysDepartmentDTO : departmentDTOList) {
            LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysDepartment::getParentId,sysDepartmentDTO.getId());
            List<SysDepartment> sysDepartmentList = departmentMapper.selectList(wrapper);
            if (!CollectionUtils.isEmpty(sysDepartmentList)) {
                List<SysDepartmentDTO> sysDepartmentDTOList = BeanHelper.copyWithCollection(sysDepartmentList, SysDepartmentDTO.class);
                getDepartmentChild(sysDepartmentDTOList);
                sysDepartmentDTO.setChildren(sysDepartmentDTOList);
            }
        }

    }
}
